#include <stdlib.h>
#include "inCheck.h"
#include "board.h"

extern Square board[10][10]; //main chessboard

/*
 *Checks if a move is legal
 */
bool is_legal_move(Square *src, Square *dest) {
        
        Piecetype type = src->type ;
        unsigned char srow = src->row;
        unsigned char scol = src->col;
        unsigned char drow = dest->row;
        unsigned char dcol = dest->col;
    
        if(drow < 1 || drow > 8 || dcol < 1 || dcol > 8) //Checks if destination is on the board
                return false;

        if(src->color == dest->color)
                return false;

        if(type == PAWN) {

                int rowdiff = abs(drow-srow);
                int coldiff = abs(dcol-scol);

                if( drow >= srow) //Pawn cannot move backwards
                        return false;

                if(coldiff > 1)
                        return false;
                        
                if(rowdiff > 2)
                        return false;        

                if(rowdiff > 1 && src->hasMoved)
                        return false;
        }

        else if(type == ROOK) {
                if(srow != drow && scol != dcol)
                        return false;
        }

        else if(type == KNIGHT) {
                
                int rowdiff = abs(drow-srow);
                int coldiff = abs(dcol-scol);
                if( (rowdiff != 1 && rowdiff != 2) || (coldiff !=1 && coldiff != 2) )
                        return false;
                if( rowdiff == 1 && coldiff !=2 )
                        return false;
                if( rowdiff == 2 && coldiff !=1 )
                        return false;
        }
 
  else if(type == BISHOP) {
                int rowdiff = abs(drow-srow);
                int coldiff = abs(dcol-scol);
                if( rowdiff != coldiff)
                        return false;
        }

        else if(type == KING) {
                int rowdiff = abs(drow-srow);
                int coldiff = abs(dcol-scol);
                if( rowdiff > 1 || coldiff > 1 )
                        return false;
        }

        else if(type == QUEEN) {
                int rowdiff = abs(drow-srow);
                int coldiff = abs(dcol-scol);
                if( rowdiff!= coldiff && srow != drow && scol != dcol )
                        return false;
        }

        return true;
}


/*
 *Initializes board;
 *Called at the start of game
 */
void init_board() {
  
      int row = 0, col = 0;

      for(row = 0; row < 10; row++) {
            for(col = 0; col < 10; col++) {
      
              if(row == 0 || row == 9 || col == 0 || col == 9) //EDGEs  
                    board[row][col] = (Square){ NOPIECE, NOCOLOR, row, col, false, false, false };
      
              else if(row == 2) //BLACK PAWNS
                    board[row][col] = (Square){ PAWN, BLACK, row, col, true, false, false };
      
              else if(row == 7) //WHITE PAWNS
                    board[row][col] = (Square){ PAWN, WHITE, row, col, true, false, false };
      
              else if(row != 1 && row != 8) //OPEN SPACES
                    board[row][col] = (Square){ NOPIECE, NOCOLOR, row, col, false, false, false };
 
            }
      }

      board[1][1] = (Square){ ROOK, WHITE, 1, 1, true, false, false };//ROOKS
      board[8][1] = (Square){ ROOK, BLACK, 8, 1, true, false, false };  
       
      board[1][2] = (Square){ KNIGHT, WHITE, 1, 2, true, false, false };//KNIGHTS
      board[8][2] = (Square){ KNIGHT, BLACK, 8, 2, true, false, false };

      board[1][3] = (Square){ BISHOP, WHITE, 1, 3, true, false, false };//BISHOPS
      board[8][3] = (Square){ BISHOP, BLACK, 8, 3, true, false, false };
      
      board[1][4] = (Square){ QUEEN, WHITE, 1, 4, true, false, false };//QUEENS
      board[8][4] = (Square){ QUEEN, BLACK, 8, 4, true, false, false };
      
      board[1][5] = (Square){ KING, WHITE, 1, 5, true, false, false };//KINGS
      board[8][5] = (Square){ KING, BLACK, 8, 5, true, false, false };  

      board[1][6] = (Square){ BISHOP, WHITE, 1, 6, true, false, false };//BISHOPs
      board[8][6] = (Square){ BISHOP, BLACK, 8, 6, true, false, false };
      
      board[1][7] = (Square){ KNIGHT, WHITE, 1, 7, true, false, false };//KNIGHTs
      board[8][7] = (Square){ KNIGHT, BLACK, 8, 7, true, false, false };
      
      board[1][8] = (Square){ ROOK, WHITE, 1, 8, true, false, false };//ROOKs
      board[8][8] = (Square){ ROOK, BLACK, 8, 8, true, false, false };
}


/*
 *Checks all the conditions for CASTLING
 */
bool is_legal_castling(int this_move, Color color) {
  
    this_move = abs(this_move);
    int king = this_move/10000;
    int k_srow = king/1000;
    int k_scol = (king/100)%10;
    int k_drow = (king%100)/10;
    int k_dcol = king%10;
          
    int rook = this_move%10000;
    int r_srow = rook/1000;
    int r_scol = (rook/100)%10;
    int r_drow = (rook%100)/10;
    int r_dcol = rook%10;
          
    if( in_check(color) )
        return false;
          
    //Check if pieces are king and rook
    if(board[k_srow + 1][k_scol + 1].type != KING || board[r_srow + 1][r_scol + 1].type != ROOK)
        return false;
    
    //Checking colors of pieces 
    if(board[k_srow + 1][k_scol + 1].color != color || board[r_srow + 1][r_scol + 1].color != color)
        return false;  
      
    //Checking colors of pieces 
    if(board[k_srow + 1][k_scol + 1].hasMoved || board[r_srow + 1][r_scol + 1].hasMoved)
        return false;
      
    //checking if all pieces are in the correct row
    //if(k_srow != 7 || k_drow != 7 || r_srow != 7 || r_drow != 7)
        //return false;
    
    //checking king source colunm      
    //if(k_scol != 4)
        //return false;
            
    //checking king destination colunm              
    if(k_dcol != 2 && k_dcol != 6)
        return false;  
   
    //checking rook source colunm           
    //if(r_scol != 0 && r_scol != 7)
        //return false;
    
    //checking rook destination colunm           
    if(r_scol == 0 && r_dcol != 3 && (board[8][2].occupied || board[8][3].occupied || board[8][4].occupied) )
        return false;
  
    //checking rook destination colunm      
    if(r_scol == 7 && r_dcol != 5 && (board[8][6].occupied || board[8][7].occupied) )
        return false;
            
    return true;
}


/*
 *Checks if a given en passant move is legal
 */
bool check_en_passant(int this_move, Color color) {
 
    int srow = (this_move%1000000)/100000;
    int scol = ((this_move%1000000)/10000)%10;
    int drow = (this_move%10000)/1000;
    int dcol = ((this_move%10000)/100)%10;
              
    int cap_row = (this_move%100)/10;
    int cap_col = this_move%10;
 
    if(board[srow + 1][scol+1].type != PAWN || board[cap_row + 1][cap_col+1].type != PAWN)
        return false;
    
    if(drow != 1) //white assumption
        return false;
        
    if( board[cap_row + 1][cap_col+1].color == board[srow + 1][scol+1].color)
       return false;
       
    if(!board[cap_row + 1][cap_col+1].pawnTwoSquareMove)
        return false;
    
    return true;
    
}


/*
 *Takes a move and updates 2D array of Squares
 */    
void update_local_board(Move *move, Color color) {

    Square src = move->src;
    Square dest = move->dest;
   
    if(move->type == CASTLING) {
        board[dest.row][dest.col] = (Square){ src.type, src.color, dest.row, dest.col, true, true, false };//king destination
        board[src.row][src.col] = (Square){ NOPIECE, NOCOLOR, src.row, src.col, false, false, false};//king source
              
        if(dest.col == 3) {       
             board[8][4] = (Square){ ROOK, color, 8, 4, true, true, false };//rook destination
             board[8][1] = (Square){ NOPIECE, NOCOLOR, 8, 1, false, false, false };//rook source
         }
    
         else if(dest.col == 7) {
             board[8][6] = (Square){ ROOK, color, 8, 6, true, true, false };//rook destination
             board[8][8] = (Square){ NOPIECE, NOCOLOR, 8, 8, false, false, false };//rook source
         } 
    }
    
    else if(move->type == ENPASSANT) {
        board[dest.row][dest.col] = (Square){ src.type, src.color, dest.row, dest.col, true, true, false };//pawn destination
        board[src.row][src.col] = (Square){ NOPIECE, NOCOLOR, src.row, src.col, false, false, false};//pawn source
        
        board[dest.row - 1][dest.col] = (Square){ NOPIECE, NOCOLOR, src.row, src.col, false, false, false };//captured piece
    }
    
    else if(move->type == PROMOTION) {
        board[dest.row][dest.col] = (Square){ dest.type, color, dest.row, dest.col, true, false, false };//new-piece destination
        board[src.row][src.col] = (Square){ NOPIECE, NOCOLOR, src.row, src.col, false, false, false};//pawn source
    }
    
    else if(move->type == NEWMOVE) {
        board[dest.row][dest.col] = (Square){ src.type, src.color, dest.row, dest.col, true, true, false };//king destination
        board[src.row][src.col] = (Square){ NOPIECE, NOCOLOR, src.row, src.col, false, false, false};//king source  
    }  
}  
      
  
































